#include <stdio.h>
#include <p18cxxx.h>
#include "LM35_temperature.h"
/***************************************************************************************
	REQUIREMENTS
		1. Temp Sensor is powered up with 5V and grounded at 0V

		2. (recommended) Buffer should be made to avoid flikering.
			without buffer, it flikers +-3.5 degrees celsius. (each measurement about 15us)
			with 10 samples buffer, it flikers +-1.5 degrees celsius.
			with 30 samples buffer, it flikers +-0.5~1 deegrees celsius.
			with 50 samples buffer, it flikers +-0.5 degrees celsius. (REASONABLE resolution)
			with 500 samples buffer, flikers go away. (TEMP_sampling_rate type needs to be larger than int type)

			Change value of TEMP_sampling_rate in between 1~255 to set sampling numbers
			

	CAUTION

		Response time exists.
		It reflects the true temperature after 1.5~3 minutes. See datasheet Fig. DS005516-27
		Time depends on the environment (moisture, etc)
		


	USAGE
		Returns the value of temperature in a byte. (need translation for use)
	
		Return Value is in between 0 ~ 255 value meaning that 0 ~ 125 degrees celsius.
		
		Using the equation, TEMP_DEGREE_CELSIUS = TEMP_RETURN_VALUE*125/256,
		we can translate into temperature value in degrees celsius.
      
    After the conversion, 
    TEMP_roundedup = roundf(TEMP_DEGREE_CELSIUS*100)/100 [include math.h for roundf()]
     to round up the decimals upto 2 decimal points.
			
		Add 273.15 to the degrees celsius value for temperature in KELVIN.
****************************************************************************************/

/**
@brief    get_temp() - gets the temperature data at the instance
@param    none
@return   int
*/
unsigned int get_temp(void)
{

	
	// Buffer Setting
//	int TEMP_sampling_rate=30; // CHANGE FOR TESTING
	double TEMP_BUFFER=0;

	int i; // counter

	// Backup Initials incase of other modules uses/changes the value of A/D conversion value
	unsigned int ADCONa_BACKUP = ADCON0;
	unsigned int ADCONb_BACKUP = ADCON1;

	// SETUP
	TRISA || 0b00000010; 	// RA1 as analog input
	ADCON0 = 0b01001001;	// Fosc/8 Select AN1, A/D on
	ADCON1 = 0x80;	// Right Justified, AN1 as analog input ## Find which AN's are Analogue and fix it latert


	for (i = 0; i < global_samples_per_measurment; i++)
	{
		//Start AD Conversion
		ADCON0bits.GO = 1; //Start AD Conversion
		while(!PIR1bits.ADIF){} //Wait for AD Conversion
		
`		TEMP_BUFFER += ADRESL;

	}
		
	TEMP_BUFFER = TEMP_BUFFER/(TEMP_sampling_rate);
	
	// Restore Backup
	ADCON0 = ADCONa_BACKUP;
	ADCON1 = ADCONb_BACKUP;

	return TEMP_BUFFER;
}


// FOR TESTING USING PORT B LEDS

/***************************************************************************************
THIS CODE IS TESTING CODE FOR TEMP SENSOR.

It writes the value of sensed value (0~255 which represents 0~125 degrees) into PORTB (LED)

the main reason is to test the optimum number of buffer size. (tested as above 30 is reasonable)

******************************************************************************************/
/* // DELETE COMMENT TO TEST

int setup(void)
{

	TRISA || 0b00000010; 	// RA1 as analog input
	

	// Test LED ## delete later
	PORTB = 0x00;
	TRISB = 0x00;

	
	ADCON0 = 0b01001001;	// Fosc/8 Select AN1, A/D on
	ADCON1 = 0x80;	// Right Justified, AN1 as analog input ## change last 4 binary digit

}	

void main(void)
{
	int TEMP_sampling_rate=200; // CHANGE FOR TESTING.
	double TEMP_BUFFER=0;
	int i;
	
	setup();
	while(1)
	{
		for (i = 0; i < TEMP_sampling_rate; i++)
		{
			//Start AD Conversion
			ADCON0bits.GO = 1; //Start AD Conversion
			while(!PIR1bits.ADIF){} //Wait for AD Conversion
			
	`		TEMP_BUFFER += ADRESL;
	
		}
		
		PORTB = TEMP_BUFFER/(TEMP_sampling_rate);
		TEMP_BUFFER=0;
	}
}

*/ // DELETE COMMENT FOR TESTING